#include "containers.h"

namespace Nesting
{
	Rectangular_box::Rectangular_box(double x_min, double y_min, double x_max, double y_max) 
		: min_x(x_min), min_y(y_min), max_x(x_max), max_y(y_max) 
	{
		assert(min_x < max_x && min_y < max_y);
	}
	
	Rectangular_box::Rectangular_box(const std::string& line_fm_filename)
	{
		std::ifstream fin(line_fm_filename.c_str());
		std::string error_info("Bad input file format: " + line_fm_filename);
		if (!fin.is_open())
			throw Bad_input("Container file cannot be openned.\n");
		std::cout<<"Open file "<<line_fm_filename<<" as container file..."<<std::endl;
		min_x = min_y = std::numeric_limits<double>::max();
		max_x = max_y = std::numeric_limits<double>::lowest();

		char vtype;
		if ( !(fin >> vtype) )
			throw Bad_input(error_info);
		while (fin)
		{
			if (vtype == 'v')
			{
				double x, y;
				if ( !(fin >> x) )
					throw Bad_input(error_info);
				if ( !(fin >> y) )
					throw Bad_input(error_info);
				min_x = std::min(min_x, x);
				min_y = std::min(min_y, y);
				max_x = std::max(max_x, x);
				max_y = std::max(max_y, y);
			}
			else if (vtype == 'e')
			{
				int x, y;
				if ( !(fin >> x) )
					throw Bad_input(error_info);
				if ( !(fin >> y) )
					throw Bad_input(error_info);
			}
			else //if (vtype != 'e')
				throw Bad_input(error_info);

			fin >> vtype;
		}
	}
	double Rectangular_box::volume() const
	{
		return (max_x - min_x) * (max_y - min_y);
	}

	void Rectangular_box::gl_draw() const
	{
		glLineWidth(2.0f);
		glColor3f(0.0f, 0.0f, 0.0f);
		glBegin(GL_LINE_LOOP);
		glVertex2d(min_x, min_y);
		glVertex2d(max_x, min_y);
		glVertex2d(max_x, max_y);
		glVertex2d(min_x, max_y);
		glEnd();
	}

	void Rectangular_box::shrink(double factor)
	{
		double new_top_y = max_y * factor;
		if (new_top_y <= min_y)	return;
		max_y = new_top_y;
	}

	void Rectangular_box::enlarge(double factor)
	{
		max_y *= factor;
	}

	bool Rectangular_box::bounded_side(const Nesting_polytope& polytope) const
	{
		const Nesting_polygon& np = dynamic_cast<const Nesting_polygon&>(polytope);
		for (unsigned int i = 0; i < np.size(); i++)
		{
			Nesting_polygon::Point v = np.vertex(i);
			if (v.x() < x_min() || v.x() > x_max())
				return false;
			if (v.y() < y_min() || v.y() > y_max())
				return false;
		}
		return true;
	}
}